#include "RegextoNFA.h"

InputCharType getInputCharType(char c)
{
    switch (c)
    {
    case '_': return UNDERLINE;
    case '+': return ADD;
    case '-': return SUB;
    case '*': return MUL;
    case '/': return DIV;
    case '%': return MOD;
    case '=': return EQ;
    case '>': return GT;
    case '<': return LT;
    case '!': return NOT;
    case '&': return AND;
    case '|': return OR;
    case '(': return LBRACKET;
    case ')': return RBRACKET;
    case '{': return LCBRAC;
    case '}': return RCBRAC;
    case ',': return COMMA;
    case ';': return SEMI;
    case '\'': return SINGLE;
    case ':': return MAO;
    case '.': return POINT;
    case '\\': return BACKQUOTE;
    default:
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
        {
            return LETTER;
        }
        else if (c >= '0' && c <= '9')
        {
            return DIGIT;
        }
        else
        {
            return EPSILON;
        }
    }
}

string getInputChartypeName(InputCharType type)
{
    switch (type)
    {
    case LETTER:
        return "LETTER";
    case UNDERLINE:
        return "UNDERLINE";
    case DIGIT:
        return "DIGIT";
    case SINGLE:
        return "'";
    case POINT:
        return "POINT";
    case ADD:
        return "+";
    case SUB:
        return "-";
    case MUL:
        return "*";
    case DIV:
        return "/";
    case MOD:
        return "%";
    case EQ:
        return "=";
    case GT:
        return ">";
    case LT:
        return "<";
    case NOT:
        return "!";
    case AND:
        return "&";
    case OR:
        return "|";
    case LBRACKET:
        return "(";
    case RBRACKET:
        return ")";
    case LCBRAC:
        return "{";
    case RCBRAC:
        return "}";
    case COMMA:
        return ",";
    case SEMI:
        return ";";
    case MAO:
        return ":";
    case BACKQUOTE:
        return "\\";
    case EPSILON:
        return "EPSILON";
    default:
        return "UNKOWN";
    }
}
unordered_map<string,int> MAP{
                {"int",1},
                {"float",2},
                {"char",3},
                {"void",4},
                {"return",5},
                {"const",6},
                {"main",7},
                {"struct",30},
                {"union",31},
                    {"switch",32},
                {"case",33},
                {"break",34},
                {"default",35}
};


string getWordTypeName(WordType type, string buffer)
{

    switch (type)
    {
    case OP_ADD:
    case OP_SUB:
    case OP_MUL:
    case OP_DIV:
    case OP_MOD:
    case OP_ASSIGN:
    case OP_GT:
    case OP_LT:
    case OP_EQ:
    case OP_LE:
    case OP_GE:
    case OP_NE:
    case OP_AND:
    case OP_OR:
    case OP_EXC:
        return "OP";

    case SE_LBRAC:
    case SE_RBRAC:
    case SE_LCBRAC:
    case SE_RCBRAC:
    case SE_COMMA:
    case SE_SEMI:
    case SE_COLON:
        return "SE";
    // case CHAR:
    //     return "char";
    case IDN:
        if(!buffer.compare("main"))
        {
            return "IDN";
        }
        if (MAP.find(buffer) != MAP.end())
        {
            return "KW";
        }
        else
        {
            return "IDN";
        }

    case INT_VAL:
        return "INT";

    case CHAR_VAL:
        return "CHAR";
    
    case FLOAT_VAL:
        return "FLOAT_VAL";
    case CHAR_B:
        return "CHAR";
    default:
        return "UNKNOWN";
    }
}



string getWordTypeContent(WordType type,string buffer)
{
    switch (type)
    {
    case OP_ADD:
    case OP_SUB:
    case OP_MUL:
    case OP_DIV:
    case OP_MOD:
    case OP_ASSIGN:
    case OP_GT:
    case OP_LT:
    case OP_EQ:
    case OP_LE:
    case OP_GE:
    case OP_NE:
    case OP_AND:
    case OP_OR:
    case OP_EXC:
        return to_string(type);

    case SE_LBRAC:
    case SE_RBRAC:
    case SE_LCBRAC:
    case SE_RCBRAC:
    case SE_COMMA:
    case SE_SEMI:
    case SE_COLON:
        return to_string(type);
    case KW_CHAR:
        return to_string(type);
    case IDN:
        //
        if (MAP.find(buffer) != MAP.end())
        {
            return to_string(MAP[buffer]);
        }

        if (!buffer.compare("char"))
        {
            return to_string(MAP[buffer]);
        }
        if (!buffer.compare("float"))
        {
            return buffer;
        }

    case INT_VAL:
        return buffer;

    case CHAR_VAL:
        return buffer;
    case FLOAT_VAL:
        return buffer;
    default:
        return buffer;
    }
}

string readfile(string filename)
{
    // 打开文件流并读取文件内容
    ifstream file;
    file.open(filename);
    if (file.is_open())
    {
        string content((istreambuf_iterator<char>(file)),
                       istreambuf_iterator<char>());
        return content;
    }
    else
    {
        cout << "error" << endl;
    }

    // 去掉换行符
    //remove函数的作用是将字符串中的 某个字符移动到字符串的末尾，并返回一个指向该字符后面位置的指针。
    //erase 函数的作用是删除字符串中指定区间内的所有字符，返回修改后的字符串
    //content.erase(remove(content.begin(), content.end(), '\n'), content.end());

    return "";
}

TokenType getTokenType(WordType type, string buffer)
{
    switch (type)
    {
    case OP_ADD:
    case OP_SUB:
    case OP_MUL:
    case OP_DIV:
    case OP_MOD:
    case OP_ASSIGN:
    case OP_GT:
    case OP_LT:
    case OP_EQ:
    case OP_LE:
    case OP_GE:
    case OP_NE:
    case OP_AND:
    case OP_OR:
    case OP_EXC:
        return TokenType::OP;

    case SE_LBRAC:
    case SE_RBRAC:
    case SE_LCBRAC:
    case SE_RCBRAC:
    case SE_COMMA:
    case SE_SEMI:
    case SE_COLON:
    case SE_Single:
        return TokenType::SE;

    case IDN:
        if (!buffer.compare("int") || !buffer.compare("void") || !buffer.compare("const") || !buffer.compare("return"))
        {
            return TokenType::KW;
        }

        else
        {
            return TokenType::IDN;
        }

    case INT_VAL:
        return TokenType::INT;
    case FLOAT_VAL:
        return TokenType::FLOAT_VAL;
    default:
        return TokenType::UNKNOWN;
    }
}

string getWordTypeName(WordType type)
{
    switch (type)
    {
    case KW_INT:
        return "KW_INT";
    case KW_VOID:
        return "KW_VOID";
    case KW_RETURN:
        return "KW_RETURN";
    case KW_CONST:
        return "KW_CONST";
    case OP_ADD:
        return "OP_ADD";
    case OP_EXC:
        return "OP_EXC";
    case OP_SUB:
        return "OP_SUB";
    case OP_MUL:
        return "OP_MUL";
    case OP_DIV:
        return "OP_DIV";
    case OP_MOD:
        return "OP_MOD";
    case OP_ASSIGN:
        return "OP_ASSIGN";
    case OP_GT:
        return "OP_GT";
    case OP_LT:
        return "OP_LT";
    case OP_EQ:
        return "OP_EQ";
    case OP_LE:
        return "OP_LE";
    case OP_GE:
        return "OP_GE";
    case OP_NE:
        return "OP_NE";
    case OP_AND:
        return "OP_AND";
    case OP_OR:
        return "OP_OR";
    case SE_LBRAC:
        return "SE_LBRAC";
    case SE_RBRAC:
        return "SE_RBRAC";
    case SE_LCBRAC:
        return "SE_LCBRAC";
    case SE_RCBRAC:
        return "SE_RCBRAC";
    case SE_COMMA:
        return "SE_COMMA";
    case SE_SEMI:
        return "SE_SEMI";
    case SE_COLON:
        return "SE_COLON";
    case SE_Single:
        return "SE_Single";
    case IDN:
        return "IDN";
    case INT_VAL:
        return "INT_VAL";
    case FLOAT_VAL:
        return "FLOAT_VAL";
    default:
        return "UNKNOWN";
    }
}

// string getGrammarName(WordType type, string buffer)
// {
//     switch (type)
//     {
//     case OP_ADD: return "+";
//     case OP_SUB: return "-";
//     case OP_MUL: return "*";
//     case OP_DIV: return "/";
//     case OP_MOD: return "%";
//     case OP_ASSIGN: return "=";
//     case OP_GT: return ">";
//     case OP_LT: return "<";
//     case OP_EQ: return "==";
//     case OP_LE: return "<=";
//     case OP_GE: return ">=";
//     case OP_NE: return "!=";
//     case OP_AND: return "&&";
//     case OP_OR: return "||";
//     case OP_EXC: return "!";
//     case SE_COLON: return ":";
//     case SE_LBRAC: return "(";
//     case SE_RBRAC: return ")";
//     case SE_LCBRAC: return "{";
//     case SE_RCBRAC: return "}";
//     case SE_COMMA: return ",";
//     case SE_SEMI: return ";";
//     case IDN:
//         if (!buffer.compare("int"))
//         {
//             return "int";
//         }
//         else if (!buffer.compare("void"))
//         {
//             return "void";
//         }
//         else if (!buffer.compare("return"))
//         {
//             return "return";
//         }
//         else if (!buffer.compare("const"))
//         {
//             return "const";
//         }
//         else
//         {
//             return "IDN";
//         }
//     case INT_VAL: return "INT";
//     case CHAR_VAL: return "char";
//     case FLOAT_VAL: return "float";
//     case CHAR_B: return "flaoa";
//     default: cerr << "Token Error: " << type << endl;
//         exit(-1);
//     }
// }
